//
//  StatusDAL.swift
//  MicroBlog
//
//  Created by 002 on 15/11/12.
//  Copyright © 2015年 002. All rights reserved.
//

import Foundation

/// 最大缓存时间
private let maxCacheDateTime: NSTimeInterval = 60 // 7 * 24 * 60 * 60

/// 数据库访问层 - 职责 专门处理本地sqlite 和 网络数据
class StatusDAL {
    
    ///  加载微博数据
    class func loadStatus(since_id: Int, max_id: Int,finished: (array : [[String : AnyObject]]?) -> ()) {
        
        // 1. 检查本地是否有缓存数据
        let array = StatusDAL.checkCacheData(since_id, max_id: max_id)
        
        // 2. 本地有就从缓存中加载数据
        if array?.count > 0 {
            print("查询到缓存数据\(array?.count)")
            
            // 回调返回本地数据
            finished(array: array!)
            return
        }
        
        print("加载网络数据")
        
        // 3. 如果没有 加载网络数据
        NetworkTools.sharedTools.loadStatus(since_id: since_id, max_id: max_id) {  (result, error) -> () in
            
            // 1->判断是否出错
            if error != nil {
                
                print("加载用户微博数据出错了")
                finished(array: nil)
                return
            }
            
            // 2->判断返回的数据是否正确
            guard let array = result?["statuses"] as? [[String: AnyObject]] else {
                
                print("数据格式错误")
                finished(array: nil)
                return
            }
            // 4. 从网络加载数据并保存到本地，方便后续使用
            StatusDAL.saveCacheData(array)
            
            // 5. 通过闭包返回网络数据
            finished(array: array)
        }

    }
    
    // 保存网络数据
    class func saveCacheData(array : [[String : AnyObject]]) {

        // 0.  用户id
        guard let userId = UserAccountViewModel.shareUserAccount.account?.uid else {
            
            print("用户未登录")
            return
        }
        // 准备数据
        // statusId ->通过字典获取
        // status ->字典序列哈
        // userId -> 登录用户
        // 1. 准备sql
        let sql = "INSERT OR REPLACE INTO T_Status (statusId, status, userId) VALUES (?, ?, ?);"
        
        // 2. 遍历数组 - 如果不能确认数据插入的消耗时间，可以在实际开发中，写测试代码
        SQLiteManager.sharedManager.queue.inTransaction({ (db, rollback) -> Void in
            
            for dict in array {
                // 1) 微博id
                let statusId = dict["id"] as! Int
                // 2）序列化字典 -> 二进制数据
                let json = try! NSJSONSerialization.dataWithJSONObject(dict, options: [])
                
                if !db.executeUpdate(sql, statusId, json, userId) {
                    print("插入数据失败")
                    // 回滚
                    rollback.memory = true
                    break
                }
            }
        })
        print("数据插入完成！")
    }
    
    ///    检查本地是否有数据
    ///
    ///  - parameter since_id: 下拉id
    ///  - parameter max_id:   上拉id
    ///
    ///  - returns: <#return value description#>
    class func checkCacheData(since_id: Int, max_id: Int) -> [[String : AnyObject]]? {
        
        // 0.  用户id
        guard let userId = UserAccountViewModel.shareUserAccount.account?.uid else {
            
            print("用户未登录")
            return nil
        }
        
        // 1. 准备sql
        var sql = "SELECT statusId, status, userId FROM T_Status \n"
        sql += "WHERE userId = \(userId) \n"
        if since_id > 0 {   // 下拉
            sql += " AND statusId > \(since_id) \n"
        } else if max_id > 0 {  // 上拉
            sql += "AND statusId < \(max_id) \n"
        }
        sql += "ORDER BY statusId DESC LIMIT 20;"
        
        print("查询数据sql:\(sql)")
        
        
        // 2. 执行sql 返回结果集
        let array = SQLiteManager.sharedManager.execRecordSet(sql)
//        print("\(array)")
//        // 遍历结果集
        var arrayM = [[String : AnyObject]]()
        
        for dict in array {
            
            let status = dict["status"] as! NSData
            
            // 反序列化 -> 一条完整微博数据字典
            let result = try! NSJSONSerialization.JSONObjectWithData(status, options: [])
            
            // 拼接数据
            arrayM.append(result as! [String : AnyObject])
        }
        
        // 返回结果 － 如果没有查询到数据，会返回一个空的数组
        return arrayM
    }
    
    /**
     1. 清理缓存工作，千万不要交给用户使用！
     2. 一定要定期清理数据库的缓存，原因
     - SQLite 的数据库，随着数据的增加，会不断的变大
     - 但是：如果删除了数据，数据库不会变小！SQLite 认为，既然数据库会涨到这么大，留出空间，准备下一次涨到这么大
     - SQLite不会再额外分配磁盘空间
     - 一般不会把 图片/音频/视频 放在数据库中，不便于检索，占用磁盘空间很大！
     */
    /// 清理`早于过期日期`的缓存数据
    class func clearDataCache() {
        
        // 1. 准备sql
        let sql = "DELETE FROM T_Status WHERE createTime < ?;"
        
        // 2. 准备日期
        let date = NSDate(timeIntervalSinceNow: -maxCacheDateTime)
        
        // 处理日期格式
        let dateFormat = NSDateFormatter()
        // 指定区域 - 在模拟器不需要，但是真机一定需要
        dateFormat.locale = NSLocale(localeIdentifier: "en")
        // 指定日期格式
        dateFormat.dateFormat = "yyyy-MM-dd HH:mm:ss"
        // 获取日期结果
        let  datestr = dateFormat.stringFromDate(date)
        
        // 3. 执行sql
        SQLiteManager.sharedManager.queue.inDatabase { (db) -> Void in
            
            if db.executeUpdate(sql, datestr) {
                print("删除了 \(db.changes()) 条缓存数据")
            }
        }
    }
    
    

}